package com.putao.base;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.putao.error.BusinessException;
import com.putao.result.JsonResult;
import com.putao.utils.StringUtils;
import org.apache.logging.log4j.util.Strings;

import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;


/**
 * @author fuhehuang
 * @email 2628279194@qq.com
 */
public class BaseController<T extends BaseDomain> {

    protected QueryWrapper<T> createWrapperAndDelFlag() {
        QueryWrapper<T> wrapper = this.createWrapper();
        return wrapper.eq("del_flag", BaseDomain.DEL_FLAG_NORMAL);
    }

    protected QueryWrapper<T> createWrapperWithUserId(String userId) {
        QueryWrapper<T> wrapper = this.createWrapper();
        return wrapper.eq("del_flag", BaseDomain.DEL_FLAG_NORMAL).eq("create_id", userId);
    }



    protected QueryWrapper<T> createWrapper(){
        return new QueryWrapper<T>();
    }

    protected QueryWrapper<T> createWrapperById(String id){
        QueryWrapper<T> wrapper = this.createWrapperAndDelFlag();
        if (StringUtils.isBlank(id)) {
            throw new BusinessException("参数异常");
        }
        return wrapper.eq("id", id);
    }

    protected QueryWrapper<T> createWrapperByIds(String ids){
        QueryWrapper<T> wrapper = this.createWrapperAndDelFlag();
        if (StringUtils.isBlank(ids)) {
            throw new BusinessException("参数异常");
        }
        if (CollectionUtil.isEmpty(StringUtils.convertList(ids))) {
            throw new BusinessException("参数异常");
        }
        return wrapper.in("id", StringUtils.convertList(ids));
    }

    protected QueryWrapper<T> orderByModifyTimeDesc(QueryWrapper<T> queryWrapper){
        return queryWrapper.orderByDesc("modify_time");
    }

    /**
     * 修改删除标记
     * @param collection
     * @param result
     * @return
     */
    protected JsonResult modifyDelFlag(Collection<T> collection, String result){
        for (T s : collection) {
            if (result.equals(s.getDelFlag())) {
                return deleteErrorByStatus(null, null);
            }
            s.setDelFlag(result);
        }
        return null;
    }

    /**
     * 根据ids删除对应数据，当sonService和columnName不为空时删除对应数据
     * @param id 多个id以,分隔
     * @param service 删除方法的service对象
     * @param sonService 用于删除子表的service对象
     * @param columnName 表字段名 下划线形式
     * @return
     */
    protected JsonResult delete(String id, IService<T> service, IService sonService, String columnName){
        if (!Strings.isNotBlank(id)){
            return argumentError(id, null);
        }
        List<String> idList = StringUtils.convertList(id);
        if (CollectionUtil.isNotEmpty(idList)) {
            if (ObjectUtil.isNotEmpty(service)) {
                JsonResult jsonResult = listAndDel(idList, service, null);
                if (ObjectUtil.isNotEmpty(jsonResult)) return jsonResult;
            }
            if (ObjectUtil.isNotEmpty(sonService) && StringUtils.isNotBlank(columnName)) {
                JsonResult jsonResult = listAndDel(idList, sonService, columnName);
                if (ObjectUtil.isNotEmpty(jsonResult)) return jsonResult;
            }
        }
        return deleteSuccess(id, null);
    }

    /**
     * 查出数据并修改删除标记
     * @param idList ID集合
     * @param service service对象
     * @param columnName 字段名，ID集合对应的字段名
     * @return 删除结果
     */
    protected JsonResult listAndDel(List<String> idList, IService<T> service, String columnName){
        Collection<T> collection;
        if (StringUtils.isNotBlank(columnName)) {
            collection = service.list(new BaseWrapper<T>().init().in(columnName, idList));
        } else {
            collection = service.listByIds(idList);
        }
        if (CollectionUtil.isNotEmpty(collection)) {
            for (T t : collection) {
                if (BaseDomain.DEL_FLAG_DELETE.equals(t.getDelFlag())) {
                    return deleteErrorByStatus(null, null);
                }
                t.updateInit();
                t.setDelFlag(BaseDomain.DEL_FLAG_DELETE);
            }
            service.updateBatchById(collection);
        }
        return null;
    }

    /**
     * 批量删除操作
     * @param id 多个id使用,拼接
     * @param service 执行删除的service实现类
     * @param consumer 消费性接口，如果需要使用id查出的数据进行操作时可以传入该接口实现类，重新accept方法，参数是根据id查出的数据集合的每个元素
     * @return JsonResult 通用返回
     */
    protected JsonResult delete(String id, IService<T> service, Consumer<T> consumer) {
        if (!Strings.isNotBlank(id)){
            return argumentError(id, null);
        }
        List<String> idList = StringUtils.convertList(id);
        boolean result = false;
        if (CollectionUtil.isNotEmpty(idList)) {
            Collection<T> list = service.listByIds(idList);
            if (CollectionUtil.isNotEmpty(list)) {
                for (T t : list) {
                    if (BaseDomain.DEL_FLAG_DELETE.equals(t.getDelFlag())) {
                        return deleteErrorByStatus(id, null);
                    }
                    t.setDelFlag(BaseDomain.DEL_FLAG_DELETE);

                }
                result = service.updateBatchById(list);
                for (T t : list) {
                    if (ObjectUtil.isNotEmpty(consumer)) {
                        consumer.accept(t);
                    }
                }
            }
        }
        return result ? deleteSuccess(id, null) : deleteNotFound(id, null);
    }

    protected  JsonResult selectSuccess(Object data, Object other){
        return JsonResult.selectSuccess(data, other);
    }

    protected  JsonResult insertSuccess(Object data, Object other){
        return JsonResult.insertSuccess(data, other);
    }

    protected  JsonResult updateSuccess(Object data, Object other){
        return JsonResult.updateSuccess(data, other);
    }

    protected  JsonResult updateNotFound(Object data, Object other){
        return JsonResult.updateNotFound(data, other);
    }

    protected  JsonResult selectNotFound(Object data, Object other){
        return JsonResult.selectNotFound(data, other);
    }

    protected  JsonResult deleteSuccess(Object data, Object other){
        return JsonResult.deleteSuccess(data, other);
    }

    protected  JsonResult deleteNotFound(Object data, Object other){
        return JsonResult.deleteNotFound(data, other);
    }
    protected  JsonResult deleteErrorByStatus(Object data, Object other){
        return JsonResult.deleteErrorByStatus(data, other);
    }

    protected  JsonResult argumentError(Object data, Object other){
        return JsonResult.argumentError(data, other);
    }

    protected  JsonResult operationSuccess(Object data, Object other){
        return JsonResult.operationSuccess(data, other);
    }
    protected  JsonResult operationFail(String message, Object data, Object other){
        return JsonResult.operationError(message, data, other);
    }
}
